/**
 * trim
 * @return {string}
 * @author mengbin
 * @since 2016/8/31
 */
String.prototype.trim = function() {
	return this.replace(/(^\s*)|(\s*$)/g, '');  
}

/**
 * left trim
 * @return {string}
 * @author mengbin
 * @since 2016/8/31
 */
String.prototype.lTrim = function() {
    return this.replace(/(^\s*)/g, '');
}

/**
 * right trim
 * @return {string}
 * @author mengbin
 * @since 2016/8/31
 */
String.prototype.rTrim = function() {
    return this.replace(/(\s*$)/g, '');
}

/**
 * replace all oldStr with newStr
 * @return {string}
 * @author mengbin
 * @since 2016/8/31
 */
String.prototype.replaceAll = function(oldStr, newStr) {
	return this.replace(new RegExp(oldStr, 'gm'), newStr);
}

/**
 * remove all space, tab, form feed, line feed (same as [\f\n\r\t\v])
 * @param obj
 * @return {string}
 * @author mengbin
 * @since 2016/8/31
 */
function trim(obj) {
	if (obj == null) {
		return '';
	}
	obj += '';
	return obj.trim();
}

/**
 * prepend '0' to day, hour, minute, second which value is less than 10
 * @param num
 * @return {string}
 * @since 2016/8/31
 * @author mengbin
 */
function prependZero(num) {
	if (typeof num != 'number') {
		num = parseInt(num);
	}
	if (num >= 10) {
		return '' + num;
	}
	return '0' + num;
}

/**
 * format Date
 * @param pattern
 * 		'yyyy-MM-dd'<br>
 * 		'yyyy/MM/dd'<br>
 *		'yyyy-MM-dd HH:mm'<br>
 *		'yyyy/MM/dd HH:mm'<br>
 *		'yyyy-MM-dd HH:mm:ss'<br>
 *		'yyyy/MM/dd HH:mm:ss'<br>
 * @return {string}
 * @author mengbin
 * @since 2016/8/31
 */
Date.prototype.format = function(pattern) {
	var yyyy = this.getFullYear(),
		MM = prependZero(this.getMonth() + 1),
		dd = prependZero(this.getDate()),
		HH = prependZero(this.getHours()),
		mm = prependZero(this.getMinutes()),
		ss = prependZero(this.getSeconds());
	
	if ('yyyy-MM-dd' == pattern) {
		return yyyy + '-' + MM + '-' + dd;
	}
	if ('yyyy/MM/dd' == pattern) {
		return yyyy + '/' + MM + '/' + dd;
	}
	if ('yyyy-MM-dd HH:mm' == pattern) {
		return yyyy + '-' + MM + '-' + dd + ' ' + HH + ':' + mm;
	}
	if ('yyyy/MM/dd HH:mm' == pattern) {
		return yyyy + '/' + MM + '/' + dd + ' ' + HH + ':' + mm;
	}
	if ('yyyy-MM-dd HH:mm:ss' == pattern) {
		return yyyy + '-' + MM + '-' + dd + ' ' + HH + ':' + mm + ':' + ss;
	}
	if ('yyyy/MM/dd HH:mm:ss' == pattern) {
		return yyyy + '/' + MM + '/' + dd + ' ' + HH + ':' + mm + ':' + ss;
	}
	return '';
}

/**
 * format Date into string like 'yyyy-MM-dd'
 * @return {string}
 * @author mengbin
 * @since 2016/8/31
 */
Date.prototype.formatDate = function() {
	return this.format('yyyy-MM-dd');
}

/**
 * format Date into string like 'yyyy-MM-dd HH:mm:ss'
 * @return {string}
 * @author mengbin
 * @since 2016/8/31
 */
Date.prototype.formatDatetime = function() {
	return this.format('yyyy-MM-dd HH:mm:ss');
}

/**
 * format date to 'yyyy-MM-dd'
 * @param str
 * @returns {string}
 * @author mengbin
 * @since 2015/8/1
 */
function formatDate(obj) {
	if (null == obj) {
		return '';
	}
	if (typeof obj == 'object') {
		var date = new Date(obj.time);
		return date.formatDate();
	}
	var date = new Date(obj);
	return date.formatDate();
}

/**
 * format date to 'yyyy-MM-dd HH:mm:ss'
 * @param str
 * @returns {String}
 * @author mengbin
 * @since 2015/8/1
 */
function formatDatetime(obj) {
	if (null == obj) {
		return '';
	}
	if (typeof obj == 'object') {
		var date = new Date(obj.time);
		return date.formatDatetime();
	}
	var date = new Date(obj);
	return date.formatDatetime();
}

/**
 * obj.toString
 * @param obj
 * @return {string}
 * @author mengbin
 * @since 2016/8/31
 */
function objToString(obj) {
	var str = '';
	for (var item in obj) {
		if (typeof(obj[item]) != 'function') {
			str += item + '=' + obj[item] + ';  ';
		}
	}
	return str;
}

/**
 * get web application root path, end with '/'
 * @return {string}
 * @since 2016/8/31
 * @author mengbin
 */
function getContextPath() {
	var requestURL = window.document.location.href;
	var requestURI = window.document.location.pathname;
	var appName = requestURI.substring(1);
	appName = appName.substring(0, appName.indexOf('/'));
	var appPath = requestURL.substring(0, requestURL.indexOf(appName) + appName.length);
	return appPath;
}

/**
 * alert ajax error
 * @param XMLHttpRequest
 * @param textStatus
 * @param errorThrown
 * @author mengbin
 * @sicne 2016/8/31
 */
function ajaxError(XMLHttpRequest, textStatus, errorThrown) {
	var msg = 'Ajax ERROR:'
		+ '\n\nError code:' + XMLHttpRequest.status
		+ (textStatus == null ? '' : '\nError info:' + textStatus)
		+ (errorThrown == null ? '' : '\nException object:' + errorThrown);
	alert(msg);
}

/**
 * display blockUI
 * @param msg
 * @param loadingPic path or base64 string of loading picture
 * @param container
 * @author mengbin
 * @since 2016/8/31
 */
function blockUI(msg, loadingPic, container) {
	msg = trim(msg) == '' ? '正在加载请稍后...' : msg;
	loadingPic = trim(loadingPic) == '' ? getContextPath() + '/resources/img/loading.gif' : loadingPic;
	
	var opts = {
		message : '<img src="' + loadingPic + '" style="width: 30px; height: 30px;">'
			+ '<div style="text-align: center; margin-top: 2px;">&nbsp;' + msg + '</div>',
		centerY: 0,
		css: {
			width: '200px',
			height: '16px',
			top: '40%',
			left: '',
			right: '40%',
			border: 'none'
		},
		overlayCSS : {
			backgroundColor: '#fff',
			opacity: '0.6',
			cursor: 'wait'
		},
		fadeIn: 0
	};
	
	if (container == null) {
		window.top.$.blockUI(opts);
	} else {
		$(container).block(opts);
	}
}

/**
 * hide blockUI
 */
function unblockUI() {
	window.top.$.unblockUI();
}

/**
 * download from specific URL
 * @param url
 * @author mengbin
 * @since 2016/8/31
 */
function downloadFromURL(url) {
	var frame = window.top.$('#this_is_my_download_frame');
	if (frame.length == 0) {
		var html = '<iframe id="this_is_my_download_frame" style="display: none"></iframe>';
		window.top.$('body').append(html);
		frame = window.top.$('#this_is_my_download_frame');
	}
	frame[0].src = url;
}

/**
 * 文件名是否是图片格式
 * @param filename
 * @returns {Boolean}
 * @author mengbin
 * @since 2016/3/29
 */
function isImage(filename) {
	if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|JPEG|PNG|BMP)$/.test(filename)) {
		return false;
	}
	return true;
}

/**
 * 验证身份证号
 * @param idNumber
 * @returns {Boolean}
 * @author mengbin
 * @since 2016/3/29
 */
function isIdNumber(idNumber) {
	idNumber = trim(idNumber);
	if (idNumber.length != 15 && idNumber.length != 18) {
		return false;
	}
	
	var city = {
		11 : "北京",
		12 : "天津",
		13 : "河北",
		14 : "山西",
		15 : "内蒙古",
		21 : "辽宁",
		22 : "吉林",
		23 : "黑龙江 ",
		31 : "上海",
		32 : "江苏",
		33 : "浙江",
		34 : "安徽",
		35 : "福建",
		36 : "江西",
		37 : "山东",
		41 : "河南",
		42 : "湖北 ",
		43 : "湖南",
		44 : "广东",
		45 : "广西",
		46 : "海南",
		50 : "重庆",
		51 : "四川",
		52 : "贵州",
		53 : "云南",
		54 : "西藏 ",
		61 : "陕西",
		62 : "甘肃",
		63 : "青海",
		64 : "宁夏",
		65 : "新疆",
		71 : "台湾",
		81 : "香港",
		82 : "澳门",
		91 : "国外 "
	};
	
	if (!idNumber
			|| !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i
					.test(idNumber)) {
		return false;
	}

	if (!city[idNumber.substr(0, 2)]) {
		return false;
	}
	
	// 18位身份证需要验证最后一位校验位
	if (idNumber.length == 18) {
		idNumber = idNumber.split('');
		// ∑(ai×Wi)(mod 11)
		// 加权因子
		var factor = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ];
		// 校验位
		var parity = [ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 ];
		var sum = 0;
		var ai = 0;
		var wi = 0;
		for (var i = 0; i < 17; i++) {
			ai = idNumber[i];
			wi = factor[i];
			sum += ai * wi;
		}
		var last = parity[sum % 11];
		if (parity[sum % 11] != idNumber[17]) {
			return false;
		}
	}
	return true;
}